package com.lorizz.docrepo;

import javax.jcr.AccessDeniedException;
import javax.jcr.ItemExistsException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.LoginException;
import javax.jcr.PathNotFoundException;
import javax.jcr.lock.LockException;
import javax.jcr.security.AccessControlException;
import javax.jcr.version.VersionException;

public class DocrepoException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    public static enum Type {
        General("a general error occurs."), 
        Login("login failed, specified credentials are invalid."),
        ItemExist("an attempt is made to place an item in a position where another item already exists"), 
        PathNotFound("no Item exists at the specified path or when the specified path implies intermediary Nodes that do not exist."),
        ItemNotFound("requested item is not found."),
        Lock("a lock-related error occurs."), 
        Version("an invalid version graph operation is attempted."),
        AccessDenied("access denied."),
        AccessControl("access control error.");

        private String description;

        Type(String description) {
            this.description = description;
        }

        public String getDescription() {
            return this.description;
        }

        public int getCode() {
            return this.ordinal();
        }
    }

    private Type type;

    public DocrepoException(String message) {
        super(message);
    }

    public DocrepoException(String message, Throwable cause) {
        super(message, cause);
        translate(cause);
    }

    public DocrepoException(Throwable cause) {
        super(cause);
        translate(cause);
    }

    private void translate(Throwable cause) {
        if (cause instanceof LoginException) {
            type = Type.Login;
        } else if (cause instanceof ItemExistsException) {
            type = Type.ItemExist;
        } else if (cause instanceof PathNotFoundException) {
            type = Type.PathNotFound;
        } else if (cause instanceof ItemNotFoundException) {
            type = Type.ItemNotFound;
        } else if (cause instanceof LockException) {
            type = Type.Lock;
        } else if (cause instanceof VersionException) {
            type = Type.Version;
        } else if (cause instanceof AccessDeniedException) {
            type = Type.AccessDenied;
        } else if (cause instanceof AccessControlException) {
            type = Type.AccessControl;
        } else {
            type = Type.General;
        }
    }

    public int getCode() {
        return type.getCode();
    }

    public String getDescription() {
        return type.getDescription();
    }
}
